package reconhecimento.util;

import reconhecimento.excecao.ImagemNulaException;
import reconhecimento.excecao.ImagensTamanhosDiferentesException;
import reconhecimento.model.Imagem;

public class Operacao {
	public static int distanciaHamem(final Imagem imagemA, final Imagem imagemB)
			throws ImagensTamanhosDiferentesException, ImagemNulaException {
		if ((imagemA == null) || (imagemB == null)) {
			throw new ImagemNulaException();
		}

		if ((imagemA.getAltura() != imagemB.getAltura())
				|| (imagemA.getLargura() != imagemB.getLargura())) {
			throw new ImagensTamanhosDiferentesException();
		}

		int distancia = 0;
		for (int i = 0; i < imagemA.getAltura(); i++) {
			for (int j = 0; j < imagemA.getLargura(); j++) {
				distancia += imagemA.getPixel(j, i) ^ imagemB.getPixel(j, i);
			}
		}

		return distancia;
	}

	public static float comparaGrades(final Imagem imagemA, final Imagem imagemB)
			throws ImagensTamanhosDiferentesException, ImagemNulaException {
		float retorno = 0;
		float modulo = 0;
		float[] gradeA, gradeB = new float[16];

		if ((imagemA == null) || (imagemB == null)) {
			throw new ImagemNulaException();
		}

		if ((imagemA.getAltura() != imagemB.getAltura())
				|| (imagemA.getLargura() != imagemB.getLargura())) {
			throw new ImagensTamanhosDiferentesException();
		}

		gradeA = informaGrade(imagemA);
		gradeB = informaGrade(imagemB);

		for (int i = 0; i < 16; i++) {
			modulo = (gradeA[i] - gradeB[i]);
			if (modulo < 0) {
				modulo = modulo * -1;
			}

			retorno = retorno + modulo;

		}

		return retorno;
	}

	public static float[] informaGrade(final Imagem imagem)
			throws ImagensTamanhosDiferentesException, ImagemNulaException {
		if (imagem == null) {
			throw new ImagemNulaException();
		}

		int temp = 1;
		int larguraCelula = imagem.getLargura() / 4;
		int alturaCelula = imagem.getAltura() / 4;
		int[] grades = new int[16];
		float[] retorno = new float[16];

		for (int i = 0; i < imagem.getAltura(); i++) {
			for (int j = 0; j < imagem.getLargura(); j++) {

				if (i < alturaCelula && j < larguraCelula) {
					grades[0] += imagem.getPixel(j, i);
				} else if (i < alturaCelula && j < larguraCelula * 2) {
					grades[1] += imagem.getPixel(j, i);
				} else if (i < alturaCelula && j < larguraCelula * 3) {
					grades[2] += imagem.getPixel(j, i);
				} else if (i < alturaCelula && j < larguraCelula * 4) {
					grades[3] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 2 && j < larguraCelula) {
					grades[4] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 2 && j < larguraCelula * 2) {
					grades[5] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 2 && j < larguraCelula * 3) {
					grades[6] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 2 && j < larguraCelula * 4) {
					grades[7] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 3 && j < larguraCelula) {
					grades[8] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 3 && j < larguraCelula * 2) {
					grades[9] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 3 && j < larguraCelula * 3) {
					grades[10] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 3 && j < larguraCelula * 4) {
					grades[11] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 4 && j < larguraCelula) {
					grades[12] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 4 && j < larguraCelula * 2) {
					grades[13] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 4 && j < larguraCelula * 3) {
					grades[14] += imagem.getPixel(j, i);
				} else if (i < alturaCelula * 4 && j < larguraCelula * 4) {
					grades[15] += imagem.getPixel(j, i);
				}
			}
		}

		for (int i = 0; i < 16; i++) {
			if (temp < grades[i]) {
				temp = grades[i];
			}
		}

		for (int i = 0; i < 16; i++) {
			retorno[i] = grades[i] / temp;
		}

		return retorno;
	}

	public int getCentroGravidadeY(Imagem imagem) {
		int resultado = 0;		
		int altura = imagem.getAltura();
		int largura = imagem.getLargura();
		
		int somaPonderada = 0;
		int denominador = 0;
		for (int i = 0; i < altura; i++) {
			int pixelsNaLinha = 0;
			for (int j = 0; j < largura; j++){
				if (imagem.getPixel(j, i) == 1){
					pixelsNaLinha++;
				}
			}
			somaPonderada += i * pixelsNaLinha;
			denominador += i;			
		}
		
		resultado = ((somaPonderada / denominador) / altura);		

		return resultado;
	}
	
	public int getCentroGravidadeX(Imagem imagem) {
		int resultado = 0;		
		int altura = imagem.getAltura();
		int largura = imagem.getLargura();
		
		int somaPonderada = 0;
		int denominador = 0;
		for (int i = 0; i < largura; i++) {
			int pixelsNaColuna = 0;
			for (int j = 0; j < altura; j++){
				if (imagem.getPixel(i, j) == 1){
					pixelsNaColuna++;
				}
			}
			somaPonderada += i * pixelsNaColuna;
			denominador += i;			
		}
		
		resultado = ((somaPonderada / denominador) / largura);		

		return resultado;
	}

}
